/**
 * 
 */
package info.niwota.fwrite;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONObject;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * @author qiangli
 * 
 */
public class Line implements Serializable, Parcelable {
	private static final long serialVersionUID = 1L;

	public static final String KEY_PEER = "pid";

	public static final String KEY_WIDTH = "w";

	public static final String KEY_HEIGHT = "h";

	private static final String KEY_ELEMENTS = "el";

	private ArrayList<Element> elements = new ArrayList<Element>();
	
	private String peer = null;

	private float height = 32;

	private float width = 0;

	public Line() {
		this(null, 0, 32);
	}
	
	public Line(String peer, int minWidth, int minHeight) {
		this.peer = peer;
		
		this.width = minWidth;
		this.height = minHeight;
	}

	public Line(JSONObject obj) throws Exception {
		this.peer = obj.getString(KEY_PEER);
		this.width = obj.getInt(KEY_WIDTH);
		this.height = obj.getInt(KEY_HEIGHT);
		
		JSONArray ja = obj.getJSONArray(KEY_ELEMENTS);
		elements.clear();
		int len   = ja.length();
		for (int i = 0; i < len; i++) {
			JSONObject o = ja.getJSONObject(i);
			elements.add(Element.toElement(o));
		}
	}
	
	public JSONObject toJSON() throws Exception {
		JSONObject obj = new JSONObject();
		
		obj.put(KEY_PEER, peer);
		obj.put(KEY_WIDTH, (int) width);
		obj.put(KEY_HEIGHT, (int) height);
		
		JSONArray ja = new JSONArray();
		
		for (Element e: elements) {
			ja.put(e.toJSON());
		}
		obj.put(KEY_ELEMENTS, ja);
		
		return obj;
	}
	
	public String getPeer() {
		return peer;
	}

	public boolean add(Element object) {
		compute(object);
		return elements.add(object);
	}

	public void add(int location, Element object) {
		compute(object);
		elements.add(location, object);
	}

	public void clear() {
		height = 0;
		width = 0;
	
		elements.clear();
	}

	public Element get(int location) {
		return elements.get(location);
	}

	public boolean isEmpty() {
		return elements.isEmpty();
	}

	public Iterator<Element> iterator() {
		return elements.iterator();
	}

	public Element remove(int location) {
		Element el = elements.remove(location);
		compute();
		return el;
	}

	public Element remove() {
		int loc = elements.size() - 1;
		if (loc >= 0) {
			Element el = elements.remove(loc);
			compute();
			return el;
		}
		return null;
	}

	public Element set(int location, GestureElement object) {
		compute(object);
		return elements.set(location, object);
	}

	public int count() {
		return elements.size();
	}

	public float getHeight() {
		return height;
	}

	public float getWidth() {
		return width;
	}

	private void compute(Element e) {
		height = Math.max(e.height, height);
		width = Math.max(e.width, width);
		//length += e.width;
	}

	private void compute() {
		height = 0;
		width = 0;
		
		for (Element e : elements) {
			compute(e);
		}
	}

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel out, int flags) {
		try {
			out.writeFloat(width);
			out.writeFloat(height);
			//out.writeFloat(length);
			out.writeList(elements);
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	private Line(Parcel in) {
		try {
			elements = in.readArrayList(this.getClass().getClassLoader());
		
			height = in.readFloat();
			width = in.readFloat();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public static final Parcelable.Creator<Line> CREATOR = new Parcelable.Creator<Line>() {
		public Line createFromParcel(Parcel in) {
			return new Line(in);
		}

		public Line[] newArray(int size) {
			return new Line[size];
		}
	};
}
